# -*- coding: utf-8 -*-

class DeliveryOrderController < ApplicationController
  before_filter :employee_authorize, :except => [:delivery_order_print_header, :delivery_order_print_content, :delivery_order_print_footer]
  before_filter :sys_before_log
  before_filter :employee_action_hx, :except => [:delivery_order_print_header, :delivery_order_print_content, :delivery_order_print_footer]
  before_filter :privilege_filter, :except => [:getAllSaleReturneds, :editDeliveryFromSaleOrder, :auditDeliveryOrderForCancel, :getProductsForEdit, :hxListForDelivery, :delivery_order_print_header, :delivery_order_print_footer, :delivery_order_print_content]

  #出库单的列表页面
  def deliveryList

  end

  #出库审批列表
  def deliveryAuditList

  end

  #显示销售订单转换为出库单的页面
  def newDeliveryFromSaleOrder

  end

  #编辑转换自己销售订单的出库单。
  def editDeliveryFromSaleOrder
    @saleOrderId = DeliveryOrder.find(params[:id]).sale_order_id
  end

  #直接使用出库单的方式，暂时不用。
  def create
    paramsHash = Util.paramsPreprocessToHash(params[:data])

    #productHash = paramsHash["products"][0]
    #取得这次入库，到入到哪个库中。
    deliveryOrder = DeliveryOrder.new
    deliveryOrder.company_id = session[:company_id]
    deliveryOrder.department_id = session[:department_id]
    deliveryOrder.employee_id = session[:employee_id]
    deliveryOrder.action_date = paramsHash['action_date']
    deliveryOrder.customer_id = paramsHash['customer_id']
    deliveryOrder.warehouse_id = paramsHash['warehouse_id']
    #deliveryOrder.to_warehouse_id = paramsHash['to_warehouse_id']
    #插入products信息
    productsHashArray = paramsHash["products"]
    productsHashArray.each do |productHash|
      deliveryOrderDetail = DeliveryOrderDetail.new
      deliveryOrderDetail.product_id = productHash["product_id"]
      deliveryOrderDetail.quantity = productHash["quantity"]
      deliveryOrderDetail.unit_price = productHash["unit_price"]
      deliveryOrder.delivery_order_details << deliveryOrderDetail
    end
    deliveryOrder.save!
    info="成功"
    result = "{success:true,info:'#{info}'}"
    render :text => result, :layout => false
  end

  #经过变更修改后，提交此方法
  #在当前，只能编辑驳回新增与驳回撤消的记录。
  def update
    paramsHash = Util.paramsPreprocessToHash(params[:data])
    #productHash = paramsHash["products"][0]
    deliveryOrder = DeliveryOrder.where("id = ? AND company_id = ? AND is_locked <> 1 AND (auditing_status is null OR auditing_status not like ?)", paramsHash['id'], session[:company_id], '%撤消%').first

    if deliveryOrder != nil
      if deliveryOrder.lock_version > paramsHash['lock_version'].to_i
        info="有其它用户在您保存之前编辑过此出库单记录，请从新编辑！"
        result = "{success:true,info:'#{info}'}"
        render :text => result, :layout => false and return false
      end
      DeliveryOrder.transaction do
        #生成历史记录
        deliveryOrderHx = DeliveryOrderHx.new
        deliveryOrderHx.company_id = deliveryOrder.company_id
        deliveryOrderHx.department_id = deliveryOrder.department_id
        deliveryOrderHx.employee_id = deliveryOrder.employee_id
        deliveryOrderHx.delivery_order_id = deliveryOrder.id
        deliveryOrderHx.sale_order_id = deliveryOrder.sale_order_id
        deliveryOrderHx.warehouse_id = deliveryOrder.warehouse_id
        deliveryOrderHx.action_date = deliveryOrder.action_date
        deliveryOrderHx.linkman = deliveryOrder.linkman
        deliveryOrderHx.phone = deliveryOrder.phone
        deliveryOrderHx.delivery_address = deliveryOrder.delivery_address

        deliveryOrder.company_id = session[:company_id]
        deliveryOrder.department_id = session[:department_id]
        deliveryOrder.employee_id = session[:employee_id]
        deliveryOrder.warehouse_id = paramsHash['warehouse_id']
        deliveryOrder.action_date = paramsHash['action_date']
        deliveryOrder.description = paramsHash['description']
        deliveryOrder.linkman = paramsHash['linkman']
        deliveryOrder.phone = paramsHash['phone']
        deliveryOrder.delivery_address = paramsHash['delivery_address']
        deliveryOrder.audit_opinion = ''
        deliveryOrder.auditor_id = ''

        if paramsHash['temporary'] == '1'
          deliveryOrder.deal_with_status = Constants::TEMP_ADD
        else
          deliveryOrder.deal_with_status = ""
          deliveryOrder.auditing_status = Constants::AUDIT_APPLY_ADD
        end

        #products信息
        productsHashArray = paramsHash["products"]
        #在这里，要作一个增，删，编辑操作，以前台数据为准。
        #首先各取出前台与后台的ID数组
        fgIdArray = Array.new
        productsHashArray.each do |productHash|
          fgIdArray << productHash["id"].to_i
        end

        bgIdArray = Array.new
        deliveryOrderDetails = deliveryOrder.delivery_order_details
        deliveryOrderDetails.each do |deliveryOrderDetail|
          bgIdArray << deliveryOrderDetail.id
          #借助此循环完成历史记录
          #变更后，记录变更过程
          deliveryOrderHxDetail = DeliveryOrderHxDetail.new
          deliveryOrderHxDetail.product_id = deliveryOrderDetail.product_id
          deliveryOrderHxDetail.quantity = deliveryOrderDetail.quantity
          deliveryOrderHxDetail.amount = deliveryOrderDetail.amount
          deliveryOrderHx.delivery_order_hx_details << deliveryOrderHxDetail
        end

        idIntersectionArray = fgIdArray & bgIdArray
        addIdArray = fgIdArray - idIntersectionArray
        delIdArray = bgIdArray - idIntersectionArray
        DeliveryOrderDetail.delete(delIdArray)

        #在进行从新整理数据之前，先把销售订单的总金额置“0”
        deliveryOrder.amount = 0
        #更新前，把汇总表中相关数据全删除了，在后面的步骤中再添加。
        ProductCollection.delete_all(["resource_type = 'DeliveryOrder' AND resource_id = ?", deliveryOrder.id])
        #生成历史记录
        deliveryOrderHx.seq_number = deliveryOrder.seq_number
        deliveryOrderHx.order_number = deliveryOrder.order_number
        deliveryOrderHx.deal_with_status = deliveryOrder.deal_with_status
        deliveryOrderHx.auditing_status = deliveryOrder.auditing_status
        deliveryOrderHx.auditor_id = deliveryOrder.auditor_id
        deliveryOrderHx.audit_opinion = deliveryOrder.audit_opinion
        deliveryOrderHx.customer_id = deliveryOrder.customer_id

        sysParam = SysParam.find_by_company_id(session[:company_id])

        productsHashArray.each do |productHash|
          #只有当用户选择的产品不为空时，才有详细订单。
          if productHash["product_id"] !=""
            #没Id说明是新增加的。
            if productHash["id"] == ""
              deliveryOrderDetail = DeliveryOrderDetail.new
              deliveryOrderDetail.product_id = productHash["product_id"]
              deliveryOrderDetail.quantity = productHash["quantity"]
              saleOrderDetail = SaleOrderDetail.where("sale_order_id = ? AND product_id = ?", deliveryOrder.sale_order_id, deliveryOrderDetail.product_id).first
              deliveryOrderDetail.amount = saleOrderDetail.unit_price * deliveryOrderDetail.quantity
              deliveryOrder.amount = deliveryOrder.amount + deliveryOrderDetail.amount #计算订单总金额
              deliveryOrderDetail.description = productHash["description"]
              deliveryOrder.delivery_order_details << deliveryOrderDetail
            else
              deliveryOrderDetail = DeliveryOrderDetail.find(productHash["id"].to_i)
              deliveryOrderDetail.product_id = productHash["product_id"]
              deliveryOrderDetail.quantity = productHash["quantity"]
              saleOrderDetail = SaleOrderDetail.where("sale_order_id = ? AND product_id = ?", deliveryOrder.sale_order_id, deliveryOrderDetail.product_id).first
              deliveryOrderDetail.amount = saleOrderDetail.unit_price * deliveryOrderDetail.quantity
              deliveryOrder.amount = deliveryOrder.amount + deliveryOrderDetail.amount #计算订单总金额
              deliveryOrderDetail.description = productHash["description"]
              deliveryOrder.delivery_order_details << deliveryOrderDetail
            end
            #同时生成结算表的内容。
            productCollection = ProductCollection.new
            productCollection.company_id = deliveryOrder.company_id
            productCollection.department_id = deliveryOrder.department_id
            productCollection.employee_id = deliveryOrder.employee_id
            productCollection.customer_id = deliveryOrder.customer_id
            productCollection.warehouse_id = deliveryOrder.warehouse_id

            productCollection.product_id = deliveryOrderDetail.product_id
            productCollection.quantity = 0 - deliveryOrderDetail.quantity
            productCollection.discount = saleOrderDetail.discount
            productCollection.unit_price = saleOrderDetail.unit_price
            productCollection.unit_amount = 0 - deliveryOrderDetail.quantity * (saleOrderDetail.amount/saleOrderDetail.quantity)
            productCollection.resource_id = deliveryOrder.id
            productCollection.resource_type = DeliveryOrder.name
            productCollection.action_date = deliveryOrder.action_date
            productCollection.description = deliveryOrderDetail.description
            #auditing_status
            if paramsHash['temporary'] == '1'
              productCollection.auditing_status = Constants::TEMP_ADD
            else
              if sysParam.audit_for_delivery_add == "是"
                productCollection.auditing_status = Constants::AUDIT_APPLY_ADD
              end
            end
            productCollection.save!
          end
        end

        deliveryOrder.save!
        deliveryOrderHx.amount = deliveryOrder.amount
        deliveryOrderHx.save!
      end
    end
    info="成功"
    result = "{success:true,info:'#{info}'}"
    render :text => result, :layout => false
  end

  def getAllDelivery
    conditionsHash = Hash.new
    paramsHash = Hash.new
    paramsHash[:offset] = params[:start].to_i
    paramsHash[:limit] = params[:limit].to_i
    conditionsStr = ''

    if params[:order_number].to_s != ''
      conditionsStr = 'delivery_orders.seq_number in (:order_number)'
      conditionsHash[:order_number] = params[:order_number].split(/,/)
    end

    if params[:customer_id].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'sale_orders.customer_id = :customer_id'
      else
        conditionsStr = conditionsStr+' AND sale_orders.customer_id = :customer_id'
      end
      conditionsHash[:customer_id] = params[:customer_id].to_i
    end

    if params[:begin_date].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'delivery_orders.action_date >= :begin_date'
      else
        conditionsStr = conditionsStr+' AND delivery_orders.action_date >= :begin_date'
      end
      conditionsHash[:begin_date] = params[:begin_date].to_date
    end

    if params[:end_date].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'delivery_orders.action_date <= :end_date'
      else
        conditionsStr = conditionsStr+' AND delivery_orders.action_date <= :end_date'
      end
      conditionsHash[:end_date] = params[:end_date].to_date
    end

    if params[:sale_order_number].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'sale_orders.seq_number in (:sale_order_number)'
      else
        conditionsStr = conditionsStr+' AND sale_orders.seq_number in (:sale_order_number)'
      end
      conditionsHash[:sale_order_number] = params[:sale_order_number].split(/,/)
    end

    #审批状态
    if params[:auditing_status].to_s != '' && params[:auditing_status] != ' '
      if conditionsStr == ''
        conditionsStr = 'delivery_orders.auditing_status like :auditing_status'
      else
        conditionsStr = conditionsStr+' AND delivery_orders.auditing_status like :auditing_status'
      end
      conditionsHash[:auditing_status] = '%'+params[:auditing_status].to_s+'%'
    elsif params[:auditing_status] == ' '
      if conditionsStr == ''
        conditionsStr = 'delivery_orders.auditing_status = :auditing_status'
      else
        conditionsStr = conditionsStr+' AND delivery_orders.auditing_status = :auditing_status'
      end
      conditionsHash[:auditing_status] = ''
    end

    #显示产品
    if params[:product_id].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'delivery_order_details.product_id = :product_id'
      else
        conditionsStr = conditionsStr+' AND delivery_order_details.product_id = :product_id'
      end
      conditionsHash[:product_id] = params[:product_id].to_i
    end

    role = Role.find(session[:role_id])
    if role.cross_company == "否"
      if conditionsStr == ''
        conditionsStr = 'delivery_orders.company_id = :company_id'
      else
        conditionsStr = conditionsStr+' AND delivery_orders.company_id = :company_id'
      end
      conditionsHash[:company_id] = session[:company_id]
    end

    count = DeliveryOrder.countAllDelivery conditionsStr, conditionsHash
    deliveries = DeliveryOrder.findAllDelivery conditionsStr, conditionsHash, paramsHash

    jsonStr="{totalProperty:"+count.to_s+",root:"+deliveries.to_json(:include => {:company => {:only => [:id, :name]}, :employee => {:only => [:id, :name]}, :department => {:only => [:id, :name]}, :warehouse => {:only => [:id, :name]}, :customer => {:only => [:id, :name]}, :sale_order => {:only => [:id, :order_number, :auditing_status, :action_date]}})+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #得到某个出库单的信息
  def getDeliveryOrderById
    deliveryOrder = DeliveryOrder.find(params[:id], :include => [:customer])
    rootStr = deliveryOrder.to_json(:include => [:customer])
    jsonStr = "{root:["+rootStr+"]}"
    render :text => jsonStr, :layout => false
  end

  #得到出库单的详细信息
  def getDeliveryOrderDetailsById
    deliveryOrder = DeliveryOrder.find(params[:delivery_order_id])
    calYear = deliveryOrder.updated_at.strftime("%Y").to_i
    calMonth = deliveryOrder.updated_at.strftime("%m").to_i

    #要判断一下权限，如果是会计权限，在这个功能里，是要显示出相应的成本的。
    if  session[:financial_management] == "是"
      #deliveryOrderDetails = DeliveryOrderDetail.joins(" dod left outer join cost_prices cp on dod.product_id = cp.product_id").where("cp.cal_year = #{calYear} AND cp.cal_month = #{calMonth} AND cp.company_id = #{session[:company_id]} AND dod.delivery_order_id = #{params[:delivery_order_id]}").select("dod.*,cp.cost_price,cp.tax_price,dod.quantity*cp.cost_price cost_amount,dod.quantity*cp.tax_price tax_amount")
      deliveryOrderDetails = DeliveryOrderDetail.joins(" dod left outer join cost_prices cp on dod.product_id = cp.product_id left outer join sale_order_details sod on sod.product_id = dod.product_id AND sod.is_locked=0").where("cp.cal_year = #{calYear} AND cp.cal_month = #{calMonth} AND cp.company_id = #{session[:company_id]} AND dod.delivery_order_id = #{params[:delivery_order_id]} AND sod.sale_order_id = #{deliveryOrder.sale_order_id}").select("dod.id,dod.description,dod.product_id,sod.unit_price,sod.discount,dod.quantity,ROUND(dod.quantity*sod.unit_price*sod.discount,2) amount,cp.cost_price,cp.tax_price,ROUND(dod.quantity*cp.cost_price,2) cost_amount,dod.quantity*cp.tax_price tax_amount")
    else
      deliveryOrderDetails = DeliveryOrderDetail.where(delivery_order_id:params[:delivery_order_id])
    end
    puts deliveryOrderDetails.length
    jsonStr="{totalProperty:"+deliveryOrderDetails.length.to_s+",root:"+deliveryOrderDetails.to_json(:include => {:product => {:only => [:id, :name, :is_suit, :spec, :number]}})+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #得到出库单的详细信息,及可出库与数存，以用于编辑，所以对于不用的记录，一定要撤消，不然数量不准。
  def getDeliveryOrderDetailsBalanceById
    deliveryOrderDetails = DeliveryOrderDetail.where(delivery_order_id:params[:delivery_order_id])

    jsonStr="{totalProperty:"+deliveryOrderDetails.length.to_s+",root:"+deliveryOrderDetails.to_json(:include => {:product => {:only => [:id, :name, :is_suit, :spec]}})+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #取得要审批的出库单
  def getAllDeliveryByAuditStatus
    conditionsHash = Hash.new
    paramsHash = Hash.new
    paramsHash[:offset] = params[:start].to_i
    paramsHash[:limit] = params[:limit].to_i
    conditionsStr = "delivery_orders.auditing_status like :auditing_status"
    conditionsHash[:auditing_status] = "%#{Constants::APPLY}%"

    if params[:order_number].to_s != ''
      conditionsStr = 'delivery_orders.seq_number in (:order_number)'
      conditionsHash[:order_number] = params[:order_number].split(/,/)
    end

    if params[:customer_id].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'sale_orders.customer_id = :customer_id'
      else
        conditionsStr = conditionsStr+' AND sale_orders.customer_id = :customer_id'
      end
      conditionsHash[:customer_id] = params[:customer_id].to_i
    end

    if params[:begin_date].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'delivery_orders.action_date >= :begin_date'
      else
        conditionsStr = conditionsStr+' AND delivery_orders.action_date >= :begin_date'
      end
      conditionsHash[:begin_date] = params[:begin_date].to_date
    end

    if params[:end_date].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'delivery_orders.action_date <= :end_date'
      else
        conditionsStr = conditionsStr+' AND delivery_orders.action_date <= :end_date'
      end
      conditionsHash[:end_date] = params[:end_date].to_date
    end

    if params[:sale_order_number].to_s != ''
      if conditionsStr == ''
        conditionsStr = 'sale_orders.seq_number in (:sale_order_number)'
      else
        conditionsStr = conditionsStr+' AND sale_orders.seq_number in (:sale_order_number)'
      end
      conditionsHash[:sale_order_number] = params[:sale_order_number].split(/,/)
    end

    count = DeliveryOrder.countAllDelivery conditionsStr, conditionsHash
    deliveries = DeliveryOrder.findAllDelivery conditionsStr, conditionsHash, paramsHash

    jsonStr="{totalProperty:"+count.to_s+",root:"+deliveries.to_json(:include => [:employee, :department, :warehouse, :customer, :sale_order])+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #查出属于某个销售订单的所有出库单，这里要列出每个出库订单的成本金额，和含税成本金额
  def getDeliveryOrdersBySaleId
    deliveryOrders = DeliveryOrder.where("sale_order_id = ?", params[:id])
    sumTaxAmount = 0
    sumCostAmount = 0
    deliveryOrders.each do |deliveryOrder|
      calYear = deliveryOrder.updated_at.strftime("%Y").to_i
      calMonth = deliveryOrder.updated_at.strftime("%m").to_i
      deliveryDetail = DeliveryOrderDetail.select("sum(cp.tax_price*dod.quantity) tax_amount,sum(ROUND(cp.cost_price*dod.quantity,2)) cost_amount").joins(" dod left join cost_prices cp on cp.product_id = dod.product_id AND cp.cal_year = #{calYear} AND cp.cal_month=#{calMonth} left join delivery_orders do on dod.delivery_order_id = do.id").where("dod.delivery_order_id = #{deliveryOrder.id} AND do.auditing_status != '#{Constants::PASS_APPLY_CANCEL}'").order("dod.id").first
      deliveryOrder.tax_amount = deliveryDetail.tax_amount
      deliveryOrder.cost_amount = deliveryDetail.cost_amount
      sumTaxAmount += deliveryOrder.tax_amount.to_f
      sumCostAmount += deliveryOrder.cost_amount.to_f
    end
    jsonStr="{totalProperty:"+deliveryOrders.length.to_s+",sum_cost_amount:#{sumCostAmount},sum_tax_amount:#{sumTaxAmount}"+",root:"+deliveryOrders.to_json(:include => [:employee, :department, :warehouse, :customer, :sale_order])+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #此方法作了调整，不用进行整单的转换，用户可对销售单进行调整，然后再保存，即一个销售单可对应多个出库单
  def transformSaleIntoDelivery
    paramsHash = Util.paramsPreprocessToHash(params[:data])

    saleOrderId = paramsHash['sale_order_id']
    warehouseId = paramsHash['warehouse_id']

    saleOrder = SaleOrder.find(saleOrderId)
    logger.info saleOrder.deal_with_status
    if saleOrder.auditing_status == Constants::PASS_APPLY_CANCEL
      info = "已经撤消的销售订单，不可以再转换为出库单！"
    elsif  saleOrder.auditing_status == Constants::AUDIT_APPLY_EDIT
      info = "销售订单的状态为:申请变更，不可以再转换为出库单！"
    elsif  saleOrder.store_status == Constants::FINISH_DELIVERY
      info = "已经出库完毕的销售订单，不可以再转换为出库单！"
    else

      #开始事务，确保在流水号正常的情况下，保存入库单时,一但出现问题，则循环执行
      begin
        Sequence.transaction do
          deliveryOrder = DeliveryOrder.new
          deliveryOrder.sale_order_id = saleOrder.id
          deliveryOrder.company_id = saleOrder.company_id
          deliveryOrder.department_id = saleOrder.department_id
          deliveryOrder.employee_id = session[:employee_id]
          deliveryOrder.action_date = paramsHash['action_date']
          deliveryOrder.customer_id = saleOrder.customer_id
          deliveryOrder.linkman = paramsHash['linkman']
          deliveryOrder.phone = paramsHash['phone']
          deliveryOrder.delivery_address = paramsHash['delivery_address']
          deliveryOrder.description = paramsHash['description']
          deliveryOrder.warehouse_id = warehouseId
          if paramsHash['temporary'] == '1'
            deliveryOrder.deal_with_status = Constants::TEMP_ADD
          else
            #这儿再判断一下，如果系统参数设定不需要审批，则直接成为通过新增。
            sysParam = SysParam.find_by_company_id(session[:company_id])
            if sysParam.audit_for_delivery_add == "否"
              deliveryOrder.auditing_status = Constants::PASS_APPLY_ADD
            else
              deliveryOrder.auditing_status = Constants::AUDIT_APPLY_ADD
            end
          end
          deliveryOrder.save! #先行保存一下，以便生成ID
          saleOrder.store_status = Constants::DELIVERING

          sysParam = SysParam.find_by_company_id(session[:company_id])

          #向详细表中插入products信息
          productsHashArray = paramsHash["products"]
          productsHashArray.each do |productHash|
            #如果不为空则加入
            if productHash["product_id"] !=""
              #得到采购订单的详细价格，只有取出它的详细记录来。
              saleOrderDetail = SaleOrderDetail.find(productHash["id"])
              deliveryOrderDetail = DeliveryOrderDetail.new
              deliveryOrderDetail.sale_order_id = saleOrder.id
              deliveryOrderDetail.product_id = productHash["product_id"]
              deliveryOrderDetail.quantity = productHash["quantity"]
              deliveryOrderDetail.unit_price = saleOrderDetail.unit_price
              deliveryOrderDetail.discount = saleOrderDetail.discount
              #用(saleOrderDetail.amount/saleOrderDetail.quantity)得到的一定是销售时的整数。这样就不存在相同情况下，出库大于销售了。
              deliveryOrderDetail.amount = (saleOrderDetail.amount/saleOrderDetail.quantity) * deliveryOrderDetail.quantity
              deliveryOrder.amount = deliveryOrder.amount + deliveryOrderDetail.amount #计算订单总金额
              deliveryOrderDetail.description = productHash["description"]
              deliveryOrder.delivery_order_details << deliveryOrderDetail
              #为了实现占货功能，现在就要插入汇总表中数据。
              #同时生成结算表的内容。
              productCollection = ProductCollection.new
              productCollection.company_id = deliveryOrder.company_id
              productCollection.department_id = deliveryOrder.department_id
              productCollection.employee_id = deliveryOrder.employee_id
              productCollection.customer_id = deliveryOrder.customer_id
              productCollection.warehouse_id = warehouseId

              productCollection.product_id = deliveryOrderDetail.product_id
              productCollection.quantity = 0 - deliveryOrderDetail.quantity
              productCollection.discount = saleOrderDetail.discount
              productCollection.unit_price = saleOrderDetail.unit_price
              productCollection.unit_amount = 0 - deliveryOrderDetail.quantity * saleOrderDetail.unit_price
              productCollection.description = deliveryOrderDetail.description
              productCollection.resource_id = deliveryOrder.id
              productCollection.resource_type = DeliveryOrder.name
              productCollection.action_date = deliveryOrder.action_date
              #deal_with_status
              if paramsHash['temporary'] == '1'
                productCollection.auditing_status = Constants::TEMP_ADD
              else
                if sysParam.audit_for_delivery_add == "是"
                  productCollection.auditing_status = Constants::AUDIT_APPLY_ADD
                end
              end

              productCollection.action_date = deliveryOrder.action_date
              productCollection.save!
            end
          end

          #在这儿再检查，对比一下销售订单与出库单的数量差，以确认要不要添加上“出库完毕”状态
          #首先要保存一下
          saleOrder.save!

          diffs = SaleOrder.diff_sale_delivery(deliveryOrder.sale_order.id)
          if diffs.length !=0
            saleOrder.store_status = Constants::DELIVERING
          elsif diffs.length ==0
            saleOrder.store_status = Constants::FINISH_DELIVERY
          end

          #开始为销售订单取得流水号
          sequence = Sequence.where("company_id = ? AND sub_type = ?", session[:company_id], DeliveryOrder.name).first

          sequence.seq_no = sequence.seq_no + 1
          deliveryOrder.seq_number = sequence.seq_no
          deliveryOrder.order_number = sequence.ab + ":" + deliveryOrder.seq_number.to_s + ":" + Date.today.to_s
          sequence.save!
          deliveryOrder.save!
          #最后保存销售订单的状态更改。
          saleOrder.save!
        end
      rescue ActiveRecord::StaleObjectError
        #这个异常是说明，你当提交时，有人提前更新了你之前读取的信息，违反乐观锁。要retry
        #这里特别指序号产生表。
        logger.info "somebody using sn before yours.............................................................."
        DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip, "StaleObjectError")
        retry
      rescue ActiveRecord::RecordNotFound
        logger.info "RecordNotFound................................................................................"
        DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip, "RecordNotFound")
      rescue Exception => e
        logger.info "logging......................................................................................."
        DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip, e.to_s)
        logger.info e
      end

      info = "成功"
    end

    result = "{success:true,info:'#{info}'}"
    render :text => result, :layout => false
  end

  #申请撤消,如果系统设置不需要审批，则直接可以撤消。
  def applyToCancel
    begin
      deliveryOrder = DeliveryOrder.find(params[:id])
      sysParam = SysParam.find_by_company_id(session[:company_id])
      if sysParam.audit_for_delivery_cancel == "否"
        deliveryOrder.auditing_status = Constants::PASS_APPLY_CANCEL
        deliveryOrder.deal_with_status = Constants::CANCELED
        ProductCollection.delete_all("resource_type = 'DeliveryOrder' AND resource_id = #{params[:id]}")

        #在审批时，要判断一下，当前的销售订单与出库订单的情况。以更新销售订单与出库订单的状态
        diffs = SaleOrder.diff_sale_delivery(deliveryOrder.sale_order.id)
        #不等于0有二种情况，一是采购的多了出库的少了，二是出的多销售的少了。不管如何，出库状态都设置为"出库中"
        if diffs.length !=0
          deliveryOrder.sale_order.store_status = Constants::DELIVERING
        elsif diffs.length ==0
          deliveryOrder.sale_order.store_status = Constants::FINISH_DELIVERY
        end
        deliveryOrder.sale_order.save!
      else
        deliveryOrder.auditing_status = Constants::AUDIT_APPLY_CANCEL
      end
      deliveryOrder.auditor_id = session[:employee_id]
      deliveryOrder.save!
    rescue Exception => e
      info = e.to_s
      logger.info info
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip, e.to_s)
    end
    info = "成功"
    result = "{success:true,info:'#{info}'}"
    render :text => result, :layout => false
  end

  #审批新增状态或变更状态。对于暂存的变为审批通过的，在pc表中要清除状态位。
  def updateAuditingStatus
    deliveryOrder = DeliveryOrder.find(params[:id])
    info = nil
    if deliveryOrder !=nil
      auditingStatus = params[:auditing_status]
      deliveryOrder.auditor_id = session[:employee_id]
      deliveryOrder.audit_opinion = params[:audit_opinion]
      DeliveryOrder.transaction do
        if (auditingStatus == "是")
          if deliveryOrder.auditing_status == Constants::AUDIT_APPLY_EDIT
            auditingStatus = Constants::PASS_APPLY_EDIT
          else
            auditingStatus = Constants::PASS_APPLY_ADD
          end
          deliveryOrder.auditing_status = auditingStatus
          #审批通过的，一定要把PC表中的状态改为""
          ProductCollection.update_all("auditing_status = ''", "resource_type = 'DeliveryOrder' AND resource_id = #{params[:id]}")
        else
          if deliveryOrder.auditing_status == Constants::AUDIT_APPLY_EDIT
            auditingStatus = Constants::REJECT_APPLY_EDIT
          else
            auditingStatus = Constants::REJECT_APPLY_ADD
          end
          deliveryOrder.auditing_status = auditingStatus
          ProductCollection.update_all("auditing_status = '#{auditingStatus}'", "resource_type = 'DeliveryOrder' AND resource_id = #{params[:id]}")
        end
        deliveryOrder.save!
      end
      #结算表处理完毕。
      info = "成功"
    else
      info = "失败，没有找到相应的销售出库单。"
    end
    result = "{success:true,info:'#{info}'}"
    render :text => result, :layout => false
  end

  #根据审批的结果，处理销售订单，如果审批同意，则取消所有入库单。同时要处理销售订单的出库状态，从新设置为出库完毕，出库中等状态。
  def updateAuditingCancelStatus
    deliveryOrder = DeliveryOrder.find(params[:id])
    DeliveryOrder.transaction do
      if params[:auditing_status]=='是'
        deliveryOrder.auditing_status = Constants::PASS_APPLY_CANCEL
        deliveryOrder.deal_with_status = Constants::CANCELED
        deliveryOrder.audit_opinion = params[:audit_opinion]
        #删除汇总表中的所有数据。
        ProductCollection.delete_all(["resource_type = 'DeliveryOrder' AND resource_id = ?", params[:id]])
      else
        deliveryOrder.audit_opinion = params[:audit_opinion]
        deliveryOrder.auditing_status = Constants::REJECT_APPLY_CANCEL
      end
      deliveryOrder.auditor_id = session[:employee_id]
      deliveryOrder.save!

      #在审批时，要判断一下，当前的销售订单与出库订单的情况。以更新销售订单与出库订单的状态
      diffs = SaleOrder.diff_sale_delivery(deliveryOrder.sale_order.id)
      #不等于0有二种情况，一是采购的多了出库的少了，二是出的多销售的少了。不管如何，出库状态都设置为"出库中"
      if diffs.length !=0
        deliveryOrder.sale_order.store_status = Constants::DELIVERING
      elsif diffs.length ==0
        deliveryOrder.sale_order.store_status = Constants::FINISH_DELIVERY
      end
      deliveryOrder.sale_order.save!
    end

    info = "成功"
    result = "{success:true,info:'#{info}'}"
    render :text => result, :layout => false
  end

  #审批出库单的预处理，提前抓出金额等供审批者参考。
  def auditDeliveryOrder
    deliveryOrder = DeliveryOrder.find(params[:id])
    saleOrder = SaleOrder.find(deliveryOrder.sale_order_id)
    #销售订单类型
    @saleOrderSaleType = saleOrder.sale_type
    #销售订单金额
    @saleOrderAmount = saleOrder.amount
    #这是某销售订单下的所有收款
    @receivableAmount = Receivable.where("sale_order_id = ? AND (auditing_status = ? OR auditing_status = ?)", deliveryOrder.sale_order_id, Constants::PASS_APPLY_ADD, Constants::PASS_APPLY_EDIT).sum(:amount)
    #本次将要出库的金额
    @currentDeliveryAmount = deliveryOrder.amount
    #已经抵消应收的出库款数额,即已经出货的金额
    @deliveriedAmount = DeliveryOrder.where("auditing_status = ? AND sale_order_id = ?", Constants::PASS_APPLY_ADD, deliveryOrder.sale_order_id).sum(:amount)
    #结合款
    @balanceAmount = @receivableAmount - @deliveriedAmount
    logger.info @receivableAmount
    logger.info @deliveriedAmount
    logger.info @currentDeliveryAmount
    logger.info @balanceAmount
  end

  #在编辑出库单时，判断可出库数量是多少。
  def getDetailsBalanceByIdForEdit
    deliveryOrderId = params[:id]
    deliveryOrder = DeliveryOrder.find(deliveryOrderId)

    deliveryOrders = DeliveryOrder.all(:select => "dd.id,p.id as product_id,p.name as product_name,p.is_suit,p.unit_price,p.number,p.spec,p.unit,dd.quantity,dd.discount,dd.amount,dd.description,newdd.quantity as dd_quantity,(sd.quantity - ifnull(newdd.quantity,0) + dd.quantity) as balance_quantity,pc.stock_quantity ", :joins => "do left join delivery_order_details dd on do.id = dd.delivery_order_id
left join (select delivery_order_id,product_id,sum(quantity) as quantity
from delivery_orders d left join delivery_order_details dd on d.id = dd.delivery_order_id
where d.sale_order_id = "+deliveryOrder.sale_order_id.to_s+" AND d.auditing_status != '#{Constants::PASS_APPLY_CANCEL}'
group by product_id) newdd on newdd.product_id = dd.product_id
left join products p on p.id = dd.product_id
left join sale_order_details sd on sd.sale_order_id = do.sale_order_id and sd.product_id = dd.product_id and sd.is_locked = 0
left join (select product_id,sum(quantity) as stock_quantity from product_collections where is_locked = 0 group by product_id) pc on pc.product_id = p.id
where do.id =  "+deliveryOrderId)

    jsonStr="{totalProperty:"+deliveryOrders.length.to_s+",root:"+deliveryOrders.to_json()+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #在编辑时得到产品的信息，同时提供这个产品的现在可出库数量，未出库数量，库存数
  def getProductsForEdit
    saleOrderId = params[:sale_order_id]
    #order_quantity是未转的数量，不代表可以转，因为有时候库存不足
    #总的思路就是显示可前本销售订单可转数，
    productIds = Array.new
    saleOrderDetails = SaleOrderDetail.where("sale_order_id = ? AND is_locked = 0", saleOrderId)
    saleOrderDetails.each do |saleOrderDetail|
      productIds << saleOrderDetail.product_id
    end
    saleOrderDetails = SaleOrderDetail.all(:select => "p.id,p.name,p.is_suit,p.unit_price,p.number,p.spec,p.unit,sd.quantity - ifnull(newdd.quantity,0) as order_quantity,case when sd.quantity - ifnull(newdd.quantity,0) > ifnull(pc.stock_quantity,0) - ifnull(newdd.quantity,0) then ifnull(pc.stock_quantity,0) - ifnull(newdd.quantity,0) else sd.quantity - ifnull(newdd.quantity,0) END as balance_quantity,ifnull(pc.stock_quantity,0) as stock_quantity ", :joins => "sd
left join (select delivery_order_id,d.sale_order_id,product_id,sum(quantity) as quantity
from delivery_orders d left join delivery_order_details dd on d.id = dd.delivery_order_id
where d.sale_order_id = "+saleOrderId+" group by product_id) newdd on newdd.product_id = sd.product_id
left join products p on p.id = sd.product_id
left join (select product_id,sum(quantity) as stock_quantity from product_collections where is_locked = 0 AND product_id in (#{productIds.join(",")}) group by product_id) pc on pc.product_id = p.id
where (sd.quantity - ifnull(newdd.quantity,0)) > 0 AND sd.sale_order_id =  "+saleOrderId)

    jsonStr="{totalProperty:"+saleOrderDetails.length.to_s+",root:"+saleOrderDetails.to_json()+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #得到变更历史的摘要
  def getHxesById
    deliveryOrderHxes = DeliveryOrderHx.where(delivery_order_id:params[:id]).includes([:department, :employee, :warehouse])
    jsonStr="{totalProperty:"+deliveryOrderHxes.length.to_s+",root:"+deliveryOrderHxes.to_json(:include => [:department, :employee, :warehouse])+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #根据变更Id得到详细信息
  def getHxDetailsByHxId
    deliveryOrderHxDetails = DeliveryOrderHxDetail.where(delivery_order_hx_id:params[:id]).includes([:product])
    jsonStr="{totalProperty:"+deliveryOrderHxDetails.length.to_s+",root:"+deliveryOrderHxDetails.to_json(:include => {:product => {:only => [:id, :name, :is_suit, :spec]}})+"}"
    #logger.info jsonStr
    render :text => jsonStr, :layout => false
  end

  #生成打印销售凭证的头部
  def delivery_order_print_header
    @deliveryOrder = DeliveryOrder.find(params[:id], :include => [:warehouse, :sale_order, :customer])
    @saleOrder = @deliveryOrder.sale_order
    @companyName = SysParam.find_by_company_id(@deliveryOrder.company_id).company_name
  end

  #生成打印销售凭证的内容
  def delivery_order_print_content
    @deliveryOrder = DeliveryOrder.find(params[:id], :include => [:delivery_order_details, :sale_order, :customer, :warehouse])
    @deliveryOrderDetails = @deliveryOrder.delivery_order_details
    #在这儿，要根据销售出库订单的销售ID与产品ID，从新取出销售明细表中的相关产品价格和折扣以及数量金额。
    @deliveryOrderDetails.each do |deliveryOrderDetail|
      saleOrderdail = SaleOrderDetail.find_by_sale_order_id_and_product_id(deliveryOrderDetail.sale_order_id, deliveryOrderDetail.product_id)
      deliveryOrderDetail.unit_price = saleOrderdail.unit_price
      deliveryOrderDetail.discount = saleOrderdail.discount
    end
    @totalQuantity = @deliveryOrderDetails.sum(:quantity)
    logger.info @totalQuantity
  end

  def delivery_order_print_footer
    @deliveryOrder = DeliveryOrder.find(params[:id], :include => [:delivery_order_details, :sale_order, :customer, :warehouse])
  end
end
